package com.biz.primus.ms.tms.service;

import com.biz.primus.common.utils.CopyUtils;
import com.biz.primus.common.vo.SpringPageVO;
import com.biz.primus.model.cat.enums.CatSaleStatusEnum;
import com.biz.primus.model.cat.enums.CatStatus;
import com.biz.primus.model.cat.vo.CatQueryVo;
import com.biz.primus.model.cat.vo.CatVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.base.vo.SpringPageToSpringPageVO;
import com.biz.primus.ms.tms.dao.po.Cat;
import com.biz.primus.ms.tms.dao.redis.CatRedisDao;
import com.biz.primus.ms.tms.dao.repository.CatRepository;
import com.biz.primus.ms.tms.dao.ro.CatRo;
import com.biz.primus.ms.tms.event.NewCatEvent;
import com.biz.primus.ms.tms.trans.CatToCatRo;
import com.biz.primus.ms.tms.trans.CatToCatVo;
import com.biz.primus.ms.tms.trans.CatVoToCat;
import com.google.common.collect.Lists;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * @author yanweijin
 * @date 2017/9/12
 */
@Slf4j
@Service
public class CatService extends AbstractBaseService {

    private final CatRepository catRepository;

    private final CatRedisDao catRedisDao;

    @Autowired
    public CatService(CatRepository catRepository, CatRedisDao catRedisDao) {
        this.catRepository = catRepository;
        this.catRedisDao = catRedisDao;
    }

    @Transactional
    public CatVo save(CatVo cat) {
        //发布异步事件
        cat.setId(idService.getNextId());
        publishEvent(new NewCatEvent(this, cat));
        Cat catPo = new CatVoToCat().apply(cat);
        saveOrUpdateUsingPo(catRepository, catRedisDao, catPo, new CatToCatRo());
        return cat;
    }

    public SpringPageVO<CatVo> findAll(CatQueryVo queryVo) {
        PageRequest pageable = queryVo.toPageRequest();
        Page<Cat> page = catRepository.findAll(pageable);
        return SpringPageToSpringPageVO.of(page, input -> CopyUtils.copyProperties(input, new CatVo()));
    }

    public CatVo get(Long id) {
        CatRo ro = catRedisDao.findOne(id);
        CatVo vo = new CatVo();
        return CopyUtils.copyProperties(ro, vo);
    }

    /**
     * 例出对应状态下的所有猫
     */
    public List<CatVo> listByStatus(CatStatus status) {

        return Lists.transform(catRepository.findByStatus(status), new CatToCatVo());
    }

    /**
     * 例出对应销售状态下的所有猫
     */
    public List<CatVo> listBySaleStatus(CatSaleStatusEnum saleStatus) {

        return Lists.transform(catRepository.findBySaleStatus(saleStatus), new CatToCatVo());
    }

    /**
     * 更新销售状态
     */
    public void updateSaleStatus(Long id, CatSaleStatusEnum saleStatus) {

        Cat cat = catRepository.findOne(id);
        cat.setSaleStatus(saleStatus);
        saveOrUpdateUsingPo(catRepository, catRedisDao, cat, new CatToCatRo());
    }

    /**
     * 事务提交成功之后才触发的事件监听器:@TransactionalEventListener
     */
    @TransactionalEventListener
    void listenNewCatEvent(NewCatEvent event) {
        log.info("listen event: {}", event);
    }


}
